<html>
<head><meta charset="utf-8"><title>A Question Of Naming Convention · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/A.20Question.20Of.20Naming.20Convention.html">A Question Of Naming Convention</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="228080892"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/A%20Question%20Of%20Naming%20Convention/near/228080892" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/A.20Question.20Of.20Naming.20Convention.html#228080892">(Feb 27 2021 at 20:25)</a>:</h4>
<p>Hi all, today we're wrapping a C function call. Here's a reduced example with shorter names:</p>
<div class="codehilite" data-code-language="C"><pre><span></span><code><span class="n">LibResult</span> <span class="n">APICALL</span> <span class="n">libGetLayers</span><span class="p">(</span><span class="kt">uint32_t</span> <span class="o">*</span><span class="n">count</span><span class="p">,</span> <span class="n">LibLayer</span> <span class="o">*</span><span class="n">layers</span><span class="p">);</span>
</code></pre></div>
<p>So here's what it looks like as an extern function in rust.</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">extern</span><span class="w"> </span><span class="s">"system"</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">libGetLayers</span><span class="p">(</span><span class="n">count</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="kt">u32</span><span class="p">,</span><span class="w"> </span><span class="n">layers</span>: <span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="n">LibLayer</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">LibResult</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>So you <em>always</em> give it a <code>count</code> and you <em>can</em> give a non-null <code>layers</code>.</p>
<ul>
<li>If <code>layers</code> is null then <code>count</code> is written with the number of layer slots you'll need to get all of them.</li>
<li>If <code>layers</code> is non-null then it's the start of a slice with <code>count</code> slots, and the function will write in the data to the slice and then <code>count</code> is written with the number of slots that were written to.</li>
</ul>
<p>A very normal C convention, lets the caller control all the allocation. Easy.</p>
<p>But in Rust we keep our pointers and lengths together in a slice so let's do that instead:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">use</span><span class="w"> </span><span class="n">core</span>::<span class="n">convert</span>::<span class="n">TryInto</span><span class="p">;</span><span class="w"> </span><span class="c1">// prelude 2021 plz ;_;</span>

<span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">lib_get_layers_count</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="nb">Result</span><span class="o">&lt;</span><span class="kt">usize</span><span class="p">,</span><span class="w"> </span><span class="n">LibResult</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">count</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0_</span><span class="k">u32</span><span class="p">;</span><span class="w"></span>
<span class="w">  </span><span class="kd">let</span><span class="w"> </span><span class="n">lib_result</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">libGetLayers</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">count</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="n">_</span><span class="p">);</span><span class="w"></span>
<span class="w">  </span><span class="k">if</span><span class="w"> </span><span class="n">lib_result</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">LIB_SUCCESS</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="nb">Ok</span><span class="p">(</span><span class="n">count</span><span class="p">.</span><span class="n">try_into</span><span class="p">().</span><span class="n">unwrap_or</span><span class="p">(</span><span class="mi">0</span><span class="p">))</span><span class="w"></span>
<span class="w">  </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="nb">Err</span><span class="p">(</span><span class="n">lib_result</span><span class="p">)</span><span class="w"></span>
<span class="w">  </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">lib_get_layers</span><span class="p">(</span><span class="n">layers</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="p">[</span><span class="n">LibLayer</span><span class="p">])</span><span class="w"> </span>-&gt; <span class="nb">Result</span><span class="o">&lt;&amp;</span><span class="k">mut</span><span class="w"> </span><span class="p">[</span><span class="n">LibLayer</span><span class="p">],</span><span class="w"> </span><span class="n">LibResult</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="c1">// theoretically this could actually panic given enough memory, whatever.</span>
<span class="w">  </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">count</span>: <span class="kt">u32</span> <span class="o">=</span><span class="w"> </span><span class="n">layers</span><span class="p">.</span><span class="n">len</span><span class="p">().</span><span class="n">try_into</span><span class="p">().</span><span class="n">unwrap</span><span class="p">();</span><span class="w"></span>
<span class="w">  </span><span class="kd">let</span><span class="w"> </span><span class="n">lib_result</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">libGetLayers</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">count</span><span class="p">,</span><span class="w"> </span><span class="n">layers</span><span class="p">.</span><span class="n">as_mut_ptr</span><span class="p">());</span><span class="w"></span>
<span class="w">  </span><span class="p">};</span><span class="w"></span>
<span class="w">  </span><span class="k">if</span><span class="w"> </span><span class="n">lib_result</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">LIB_SUCCESS</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="nb">Ok</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">layers</span><span class="p">[</span><span class="o">..</span><span class="n">count</span><span class="p">.</span><span class="n">try_into</span><span class="p">().</span><span class="n">unwrap</span><span class="p">()])</span><span class="w"></span>
<span class="w">  </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="nb">Err</span><span class="p">(</span><span class="n">lib_result</span><span class="p">)</span><span class="w"></span>
<span class="w">  </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>"but Lokathor, almost no one wants to allocate that themselves! that's still a whole extra step!"</p>
<p>Alright, I got you:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#[cfg(feature = </span><span class="s">"alloc"</span><span class="cp">)]</span><span class="w"></span>
<span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">frob</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="nb">Result</span><span class="o">&lt;</span><span class="nb">Vec</span><span class="o">&lt;</span><span class="n">LibLayer</span><span class="o">&gt;</span><span class="p">,</span><span class="w"> </span><span class="n">LibResult</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="kd">let</span><span class="w"> </span><span class="n">expected</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">lib_get_layers_count</span><span class="p">()</span><span class="o">?</span><span class="p">;</span><span class="w"></span>
<span class="w">  </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Vec</span>::<span class="n">with_capacity</span><span class="p">(</span><span class="n">expected</span><span class="p">);</span><span class="w"></span>
<span class="w">  </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">actual_u32</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0_</span><span class="k">u32</span><span class="p">;</span><span class="w"></span>
<span class="w">  </span><span class="kd">let</span><span class="w"> </span><span class="n">lib_result</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">libGetLayers</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">actual_u32</span><span class="p">,</span><span class="w"> </span><span class="n">expected</span><span class="p">.</span><span class="n">as_mut_ptr</span><span class="p">());</span><span class="w"></span>
<span class="w">  </span><span class="p">};</span><span class="w"></span>
<span class="w">  </span><span class="kd">let</span><span class="w"> </span><span class="n">actual_usize</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">actual_u32</span><span class="p">.</span><span class="n">try_into</span><span class="p">().</span><span class="n">unwrap_or</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span><span class="w"></span>
<span class="w">  </span><span class="k">if</span><span class="w"> </span><span class="n">actual_usize</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="n">expected</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="fm">panic!</span><span class="p">(</span><span class="s">"lib did a buffer overflow!"</span><span class="p">);</span><span class="w"></span>
<span class="w">  </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">v</span><span class="p">.</span><span class="n">set_len</span><span class="p">(</span><span class="n">actual_usize</span><span class="p">)</span><span class="w"> </span><span class="p">};</span><span class="w"></span>
<span class="w">  </span><span class="p">}</span><span class="w"></span>
<span class="w">  </span><span class="k">if</span><span class="w"> </span><span class="n">lib_result</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">LIB_SUCCESS</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="nb">Ok</span><span class="p">(</span><span class="n">v</span><span class="p">)</span><span class="w"></span>
<span class="w">  </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="nb">Err</span><span class="p">(</span><span class="n">lib_result</span><span class="p">)</span><span class="w"></span>
<span class="w">  </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>So here is the question that I'm finally getting around to: What would you expect the name of <code>frob</code> to be? What sort of naming convention would you use? What's the verb that we want to give, if there's any special verb at all, for "I will allocate for you", considering that there is also the non-allocating version available in the same package.</p>



<a name="228081342"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/A%20Question%20Of%20Naming%20Convention/near/228081342" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Steven Fackler <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/A.20Question.20Of.20Naming.20Convention.html#228081342">(Feb 27 2021 at 20:33)</a>:</h4>
<p>I think I've used <code>lib_get_layers_owned</code> for the frob version in similar circumstances in the openssl crate</p>



<a name="228083777"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/A%20Question%20Of%20Naming%20Convention/near/228083777" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/A.20Question.20Of.20Naming.20Convention.html#228083777">(Feb 27 2021 at 21:18)</a>:</h4>
<p>Another option is <code>lib_put_layers</code> or <code>lib_get_layers_in{_place,to}</code> for the <code>&amp;mut []</code>-based API, and <code>get_layers</code> for the <code>-&gt; Vec</code> one <span aria-label="shrug" class="emoji emoji-1f937" role="img" title="shrug">:shrug:</span></p>



<a name="228086365"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/A%20Question%20Of%20Naming%20Convention/near/228086365" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/A.20Question.20Of.20Naming.20Convention.html#228086365">(Feb 27 2021 at 22:12)</a>:</h4>
<p>_owned and _to for slices are both good.</p>



<a name="228544366"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/A%20Question%20Of%20Naming%20Convention/near/228544366" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/A.20Question.20Of.20Naming.20Convention.html#228544366">(Mar 03 2021 at 06:36)</a>:</h4>
<p>I think I would expect a boxed slice unless there's reason to believe the caller will resize it.</p>



<a name="228544395"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/A%20Question%20Of%20Naming%20Convention/near/228544395" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/A.20Question.20Of.20Naming.20Convention.html#228544395">(Mar 03 2021 at 06:37)</a>:</h4>
<p>And yeah, get_layers for the natural one that allocates.</p>



<a name="228544417"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/A%20Question%20Of%20Naming%20Convention/near/228544417" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/A.20Question.20Of.20Naming.20Convention.html#228544417">(Mar 03 2021 at 06:37)</a>:</h4>
<p>And _to for the one that takes a slice.</p>



<a name="228544642"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/A%20Question%20Of%20Naming%20Convention/near/228544642" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/A.20Question.20Of.20Naming.20Convention.html#228544642">(Mar 03 2021 at 06:40)</a>:</h4>
<p>Well, boxed slice is like, a vec but not as good, basically, right?</p>



<a name="228585476"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/A%20Question%20Of%20Naming%20Convention/near/228585476" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/A.20Question.20Of.20Naming.20Convention.html#228585476">(Mar 03 2021 at 12:52)</a>:</h4>
<p>I always use boxed slice where possible and when they can be conveniently generated, because boxed slices are smaller and also express the lack of excess capacity, so for instance if I collect an <code>ExactSizeIterator</code> I pass a <code>Box&lt;[T]&gt;</code> out of the function. There is some ergonomics loss due to holes in std but I think this is a contingent fact and in any case you can compensate with extension methods to some extent</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>